print("Core loading...")

local basicEnvironment = {}
for k,v in pairs(_G) do
  basicEnvironment[k] = v
end
basicEnvironment = basicEnvironment
basicEnvironment.__index = basicEnvironment

function init(sheetPtr)
  _shPtr = sheetPtr
  corefuncs.RawLogPrint(_shPtr, "Core initializing...")
  Core = {}
  basicEnvironment.Core = Core
  for k,v in pairs(corefuncs) do
    if string.sub(k, 1, 3) == "Raw" then
      Core[string.sub(k, 4, -1)] = function (...)
        return corefuncs[k](_shPtr, unpack(arg))
      end
    end
    corefuncs.RawLogPrint(_shPtr, "Core function: " .. k)
  end
  corefuncs.RawLogPrint(_shPtr, "Core done initializing.")
end

function setTopLevelTable(topLevelTable)
  _tlt = topLevelTable
end

-- this should do whatever it needs to do with the static table
-- (I don't quite remember what that was...)
function produceCppPrototype(staticTable, className)
  -- might as well list anything in here....
  for k,v in pairs(staticTable) do
    corefuncs.RawLogPrint(_shPtr, className .. "." .. k)
  end
  staticTable._className = className
  staticTable.__index = staticTable
  setmetatable(staticTable, basicEnvironment)
end

function makeInheritFunction(className)
  local cname = className
  local ret = function (pname)
    corefuncs.RawSetInheritance(_shPtr, cname, pname)
  end
  return ret
end

function simplePrint(str)
  corefuncs.RawLogPrint(_shPtr, tostring(str))
end

function makeSuperFunction(tab)
  local t2 = tab
  local ret = function ()
    return getmetatable(t2)
  end
  return ret
end

function produceConsoleEnv(chan)
  local rprint = corefuncs.RawConPrint
  local shptr = _shPtr
  local cprint = function (str)
    rprint(shptr, chan, tostring(str))
  end
  local bcast = function (str)
    rprint(shptr, -1, tostring(str))
  end
  local newTable = {}
  newTable._G = _G
  newTable.print = cprint
  newTable.bcast = bcast
  newTable.chan = chan
  newTable.Top = _tlt
  newTable.TopObjects = _tlt
  setmetatable(newTable, basicEnvironment)
  return newTable
end

function execConCmd(chan, str)
  _chans = _chans or {}
  if _chans[chan] == nil then _chans[chan] = produceConsoleEnv(chan) end
  local tempchunk, err = loadstring(str)
  if tempchunk == nil then
    corefuncs.RawConPrint(_shPtr, chan, err)
  else
    setfenv(tempchunk, _chans[chan])
    tempchunk()
  end
end

function producePrototype(protoChunk, newTable, className, parentName)
  -- basically just set the protoChunk's environment to the table and run it
  newTable._G = _G
  newTable._className = className
  newTable._parentName = parentName
  newTable.inherit = makeInheritFunction(className)
  newTable.TopObjects = _tlt
  newTable.Top = _tlt
  newTable.print = simplePrint
  newTable.__index = newTable
  newTable.super = makeSuperFunction(newTable)
  setfenv(protoChunk, newTable)
  protoChunk()
  -- you shouldn't be able to inherit after the fact!
  newTable.inherit = nil
end

function makeInstanceTable()
  -- I also forget if there was anything special that was supposed to happen in here...
  local ret = {}
  return ret
end

print("Core loaded.")